
#include "include.h"
#include "timer.h"



#define BT_CLK_N REG32(ADDR_REG_CLKN)


/***
* **************************#########Timer##########************************************
*/

UtilTimer_t __xdata util_timer;

PUBLIC void TMR_Init(void)
{
	u8_t i;
	//u32_t clk = bt_clk_n;
	util_timer.timer_flages = 0;
	util_timer.last_timer = BT_CLK_N;
	for(i = 0; i < UTIL_TIMER_NUM; i++){
		util_timer.callback[i] = NULL;
		util_timer.timer_end[i] = 0;
	}
	return;
}

PUBLIC bool TMR_Start10Ms(u16_t time_in_10ms, p_TimerCallback callback, u8_t* timer_id)
{
	u8_t i = 0;
	u32_t clk = BT_CLK_N;
	
	//do we have enough timers?
	if(util_timer.timer_flages == 0xff){
		return false;
	}
	while(i < UTIL_TIMER_NUM){
		if(!((util_timer.timer_flages >> i) & 1)){
			if(timer_id)
				*timer_id = i;
			break;
		}
		++i;
	}
	util_timer.timer_flages |= 1 << i;
	util_timer.callback[i] = callback;
	util_timer.timer_end[i] = clk + (u32_t)time_in_10ms * 32;
	return true;
}

PUBLIC bool TMR_StartSecond(u16_t time_in_second, p_TimerCallback callback, u8_t* timer_id)
{
	return(TMR_Start10Ms(time_in_second*100, callback, timer_id));
}


PUBLIC bool TMR_Stop( u8_t timer_id)
{
	if((timer_id > 8) ||!((util_timer.timer_flages >> timer_id) & 1))
		return false;
	util_timer.timer_flages &= ~( 1<< timer_id);
	util_timer.callback[timer_id] = NULL;
	util_timer.timer_end[timer_id] = 0;
	return true;
}
PUBLIC void TMR_Process(void)
{
	u8_t i;
	// handle the rollback
	u32_t clk = BT_CLK_N;
	
	if(util_timer.last_timer > (clk + 0x1000)){
		for(i = 0; i < UTIL_TIMER_NUM; ++i){
			if((util_timer.timer_flages >> i) & 1){
				 util_timer.timer_end[i] = (util_timer.timer_end[i] > util_timer.last_timer) ? \
             	 		 (util_timer.timer_end[i] -util_timer.last_timer + clk) : \
               			 (util_timer.last_timer-util_timer.timer_end[i] + clk);
			}
		}
	}
	util_timer.last_timer = clk;
	
	for(i = 0; i < UTIL_TIMER_NUM; ++i){
		if((util_timer.timer_flages >> i) & 1){
			if(util_timer.timer_end[i] < clk){
				util_timer.timer_flages &=~( 1<< i); // clear the flag
				util_timer.callback[i](i);
			}
		}
	}
	return;
}


